<?php

namespace app\controller\admin\module\index\components;

use app\components\traits\Singleton;
use Exception;

class Statistics
{
    use Singleton;

    private string $date;
    private array $list;
    private array $data;

    private string $timeField;

    private array $weekReplace = [
        '1' => '一',
        '2' => '二',
        '3' => '三',
        '4' => '四',
        '5' => '五',
        '6' => '六',
        '7' => '日',
    ];


    /**
     * 初始化数据
     * @param string $mode
     * @param string $model
     * @param string $timeField
     * @param string $field
     * @return $this
     * @throws Exception
     */
    public function initializationList(string $mode, string $model, string $timeField, string $field): Statistics
    {
        $this->timeField = $timeField;
        [$this->date, $this->list, $this->data] = ['', [], []];
        [$timer, $date] = $this->getDate($mode);
        if(empty($timer)){
            throw new Exception('错误的类型');
        }
        $list = Model($model)->getList([
            [$this->timeField, 'between', [reset($timer), end($timer)]],
        ], $field);
        $data = [];
        foreach($timer as $v){
            $data[strtotime(date($date, $v))] = 0;
        }
        [$this->date, $this->list, $this->data] = [$date, $list, $data];
        return $this;
    }

    /**
     * 获取数据
     * @return array
     */
    public function corporealList(): array
    {
        if(!empty($this->list)) {
            foreach ($this->list as $v) {
                isset($this->data[strtotime(date($this->date, $v[$this->timeField]))]) and $this->data[strtotime(date($this->date, $v[$this->timeField]))]++;
            }
            array_multisort(array_keys($this->data), SORT_ASC, $this->data);
        }
        return array_values($this->data);
    }

    /**
     * 获取日期
     * @param string $mode
     * @param bool $flag
     * @return array
     */
    public function getDate(string $mode, bool $flag = false): array
    {
        $timer = [];
        switch ($mode){
            case 'week':
                $currentDate = date('Y-m-d');
                $dayOfWeek = date('N', strtotime($currentDate));
                $monDay = date('Y-m-d', strtotime($currentDate . ' -' . ($dayOfWeek - 1) . ' days'));
                for($i = 1; $i <= 7; $i++){
                    $time = strtotime($monDay . ' +' . ($i - 1) . ' days');
                    $timer[] = $flag ? str_replace(array_keys($this->weekReplace), array_values($this->weekReplace), (date('周N', $time))) : $time;
                }
                $date = 'Y-m-d';
                break;
            case 'month':
                for($i = 1; $i <= 12; $i++){
                    $time = strtotime(date('Y-01-01') . ' +' . ($i - 1) . ' month');
                    $timer[] = $flag ? date('m月', $time) : $time;
                }
                $date = 'Y-m-01';
                break;
            case 'year':
                $yearNumber = 5;    //五年
                for($i = ($yearNumber - 1); $i >= 0; $i--){
                    $time = strtotime(date('Y-01-01', strtotime(date('Y-m-d'))) . ' -' . $i . ' year');
                    $timer[] = $flag ? date('Y年', $time) : $time;
                }
                $date = 'Y-01-01';
                break;
            default:
                return [$timer, ''];
        }
        end($timer);
        $flag or $timer[key($timer)] = strtotime(date('Y-m-d H:i:s', end($timer)) . '+ 1 ' . ($mode == 'week' ? 'days' : $mode)) - 1;
        return [$timer, $date];
    }

    /**
     * 获取今日注册用户数
     * @return int
     */
    public function getTodayRegisterUserNumber(): int
    {
        return Model('user')->getCount([['createtime', 'between', [strtotime(date('Y-m-d')), strtotime(date('Y-m-d 23:59:59'))]]]);
    }

    /**
     * 获取总注册用户数
     * @return int
     */
    public function getTotalRegisterUserNumber(): int
    {
        //五年内的注册用户数
        return Model('user')->getCount([['createtime', 'between', [strtotime(date('Y-01-01', strtotime(date('Y-m-d'))) . ' -4 year'), strtotime(date('Y-m-d 23:59:59'))]]]);
    }

    /**
     * 获取今日房间数
     * @return int
     */
    public function getTodayRoomNumber(): int
    {
        return Model('room')->getCount([['addtime', 'between', [strtotime(date('Y-m-d')), strtotime(date('Y-m-d 23:59:59'))]]]);
    }

    /**
     * 获取总房间数
     * @return int
     */
    public function getTotalRoomNumber(): int
    {
        //五年内的注册用户数
        return Model('room')->getCount([['addtime', 'between', [strtotime(date('Y-01-01', strtotime(date('Y-m-d'))) . ' -4 year'), strtotime(date('Y-m-d 23:59:59'))]]]);
    }
}

